$logger = Logger.new('./log/debug.log')

class Lily
	Name = 'whitzlily'
	Version = '0.7'

	def initialize(cgi,env)
		@cgi                 = cgi
		@blog_title          = env['blog_title']
		@blog_description    = env['blog_description']
		@blog_language       = env['blog_language']
		@userid              = env['userid']
		@password            = env['password']
		@datadir             = env['datadir']
		@flavourdir          = env['flavourdir']
		@num_entries         = env['num_entries'].to_i
		@additional_loadpath = env['additional_loadpath']
		@default_flavour     = env['default_flavour']
		@default_suffix      = env['default_suffix']
		@show_future_entries = env['show_future_entries'].to_i
		@plugindir           = env['plugindir']
		@encode              = env['encode']
		@file_extension      = env['file_extension'].split(/ /)
		@editable_extension  = env['editable_extension'].split(/ /)
		@author              = env['author']
		@mail                = env['mail']
		@dateformat          = env['dateformat']
		if env['url'] == ""
			@url = "http://#{@cgi.server_name}#{@cgi.script_name}"
		else
			@url = env['url']
		end
		$LOAD_PATH.unshift(@additional_loadpath) if @additional_loadpath != ''
		@env = env

		Dir.glob("#{@plugindir}/*.rb").sort.each {|f|
			File::open(f,"r"){|src|
				#begin
					self.instance_eval(src.read, f)
				#rescue Exception
				#end
			}
		}

		@ptimes = EntryStates.new("#{@datadir}/.entrydate")
	end

	def enc_char
		'utf-8'
	end

	def get_conf(name)
		begin
			if name =~ /(.+)::(.+)/
				eval("#{$1}_#{$2}")
			else
				eval("@#{name}")
			end
		rescue NameError
			error_out()
		end
	end
	
	def get_post_time(file)
		@ptimes[file] || @ptimes.add(file)
	end
	
	def disp
		@stories   = []
		@echo_off = false

		@options = Options.new(@cgi.path_info, @default_flavour, @env)
		
		if @options.article?
			if File.file?("#{@datadir}#{@options.path}")
				@stories.push("#{@datadir}#{@options.path}")
			end
		else
			@file_extension.each {|fext|
				optpath = (@options.path == '') ? @options.path : @options.path + '/'
				files = Dir.glob("#{@datadir}/#{optpath}**/*.#{fext}")
				files.each {|f|
					day = get_post_time(f)
					@stories.push(f) if @options.join?(day)
				}
			}
		end
		
		# sort & slice
		@stories = @stories.sort_by {|f| get_post_time(f) }
		@stories.reverse!
		if (@options.index? && !@options.has_date?)
			@stories = @stories[0, @num_entries]
		end
		
		# plugin
		Dir.glob("#{@plugindir}/*.rb").sort.each {|f|
			#begin
				eval("#{File.basename(f,".*").downcase}", binding(), f)
			#rescue NameError
			#end
		}

		# print
		unless @echo_off
			header = {}
			not_found = false

			fc = 'text/html'
			content_flav = "#{@flavourdir}/#{@options.flavour}/content_type"
			fc = File.read(content_flav) if File.exist?(content_flav)
			@csspath = "#{@url}/#{@flavourdir}"

			not_found = true if (@stories.empty? && !@editable_extension.index(@options.flavour))

			header['status'] = CGI::HTTP_STATUS['NOT_FOUND'] if not_found
			header['type'] = fc.chomp
			header['charset'] = enc_char

			print @cgi.header(header)

			disp_flav('head')

			unless not_found
				@prev_story_date = nil
				@stories.each {|f| disp_story(f) }
			else
				print '404 Error, Page Not Found.'
			end
			
			disp_flav('foot')
		end
	end
	
	def disp_flav(flav_type)
		if File.file?("#{@flavourdir}/#{@options.flavour}/#{flav_type}")
			fn = "#{@flavourdir}/#{@options.flavour}/#{flav_type}"
		else
			fn = "#{@flavourdir}/#{@default_flavour}/#{flav_type}"
		end

		print Erubis::EscapedEruby.load_file(fn).result(binding)
	end
	
	def disp_story(file)
		File.open(file) {|f|
			@title = f.gets.chomp
			@body = f.read
			path = Path.new(file, @datadir)
			@path, @fn, @fext, @category = path.path, path.filename, path.suffix, path.category
		}
		@body_plain = @body.dup

		Dir.glob("#{@plugindir}/*.rb"){|f|
			begin
				eval("#{File.basename(f,".*").downcase}_filter")
			rescue NameError
			end
		}

		@mtime = File.mtime(file)
		disp_flav(@options.content_flavour)
	end

end

def error_out
	e = $!

	puts "Status: 500 Internal Server Error"
	puts "Content-Type: text/html; charset=us-ascii\n\n"
	puts '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'
	puts "<html><head><title>500 Internal Server Error</title></head><body>"
	puts '<h1>Internal Server Error</h1>'
	puts "<p>#{e.class}: #{e.to_s}</p>"
	puts '<ul>'
	e.backtrace.each {|trace| puts "<li>#{CGI.escapeHTML(trace)}</li>" }
	puts '</ul>'
	puts "<hr><address>#{Lily::Name}/#{Lily::Version}</address>"
	puts '</body></html>'
	exit
end

def load_env(cfg)
	env = Hash.new

	IO.readlines(cfg).each {|line|
		item = line.chomp.split(/\s+/)
		key = item.shift
		env[key] = item.join(' ')
	}
	
	return env
end
